#!/usr/bin/env node
"use strict";
/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { resolve, join, delimiter } from 'node:path';
import { createHash } from 'node:crypto';
import { readdirSync, statSync, existsSync, readFileSync, renameSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { execSync } from 'node:child_process';

function execCommand(command, workdir) {
  console.log(`执行命令: ${command}, 工作目录: ${workdir}`);
  return execSync(command, { cwd: workdir, stdio: 'inherit' });
}

function getNpm() {
  const pathDirs = process.env.PATH.split(delimiter);
  const npmDir = pathDirs.find(dir => {
    const npmPath = join(dir, 'npm');
    const npmExists = existsSync(npmPath) && statSync(npmPath).isFile();
    const notContainsDeveco = !dir.toLowerCase().includes('deveco');
    return npmExists && notContainsDeveco;
  });
  return npmDir? `"${join(npmDir, 'npm')}"`: 'npm';
}

function getConfigHash() {
  const configPath = resolve('hvigor', 'hvigor-config.json5');
  if (existsSync(configPath)) {
    const configContent = readFileSync(configPath);
    const currentHash = createHash('sha256').update(configContent).digest('hex');
    console.log(`配置文件 hash: ${currentHash.substring(0, 8)}...`);
    return currentHash;
  }
  console.log('未找到 hvigor-config.json5，使用默认 hash');
  return 'default-hash';
}

function checkLock(hash) {
  if (existsSync(resolve('.plugin-build.lock'))) {
    const lockContent = readFileSync(resolve('.plugin-build.lock'), { encoding: 'utf-8' });
    if (lockContent.includes(hash)) {
      console.log('🔒 配置未变更，跳过构建');
      return true;
    }
  }
  console.log('🔄 配置已变更或首次构建');
  return false;
}

function generateBuildLock(hash) {
  writeFileSync(resolve('.plugin-build.lock'), hash, { encoding: 'utf-8' });
}

function clearDir(targetDir) {
  console.log(`清理目录: ${targetDir}`);
  if (existsSync(targetDir)) {
    rmSync(targetDir, { recursive: true, force: true });
  }
}

function ensureDir(targetDir) {
  if (!existsSync(targetDir)) {
    console.log(`创建目录: ${targetDir}`);
    mkdirSync(targetDir, { recursive: true });
  }
}

function buildPlugin(pluginDir) {
  console.log(`构建插件: ${pluginDir}`);
  if (!existsSync(join(pluginDir, 'package.json'))) {
    console.log(`跳过 ${pluginDir}: 没有 package.json`);
    return;
  }

  // 清理dist目录，避免ts文件删除后js文件残留
  const distDir = resolve(pluginDir, 'dist');
  if (existsSync(distDir)) {
    console.log(`清理 dist 目录: ${distDir}`);
    rmSync(distDir, { recursive: true, force: true });
  }

  execCommand(`${getNpm()} install --loglevel error`, pluginDir);
  execCommand(`npx tsc && npm pack`, pluginDir);
}

function moveArtifact(pluginDir) {
  console.log(`移动构建产物: ${pluginDir}`);
  const packageData = readFileSync(resolve(pluginDir, 'package.json'));
  const npmPackageInfo = JSON.parse(packageData);
  const packageFileName =
    `${npmPackageInfo.name.replaceAll('@', '').replaceAll('/', '-')}-${npmPackageInfo.version}.tgz`;

  const sourcePath = resolve(pluginDir, packageFileName);
  const targetPath = resolve('tpc', 'outputs', 'plugin', packageFileName);

  if (existsSync(sourcePath)) {
    renameSync(sourcePath, targetPath);
    console.log(`✅ 已移动: ${packageFileName}`);
  }
}

function signArtifacts() {
  const artifactsDir = resolve('tpc', 'outputs', 'plugin');
  console.log(`生成 SHA256 签名: ${artifactsDir}`);

  const artifactFiles = readdirSync(artifactsDir);
  const manifestLines = [];

  for (const file of artifactFiles) {
    const fullPath = join(artifactsDir, file);
    const stats = statSync(fullPath);

    if (stats.isFile() && file.endsWith('.tgz')) {
      const content = readFileSync(fullPath);
      const hash = createHash('sha256').update(content).digest('hex');

      // 生成单独的 .sha256 文件
      writeFileSync(resolve(artifactsDir, `${file}.sha256`), `${hash}  ${file}\n`, { encoding: 'utf-8' });

      // 添加到清单
      manifestLines.push(`${hash}  ${file}`);
      console.log(`✅ SHA256: ${file} (${hash.substring(0, 16)}...)`);
    }
  }

  // 生成 SHA256SUMS 清单文件
  if (manifestLines.length > 0) {
    writeFileSync(resolve(artifactsDir, 'SHA256SUMS'), manifestLines.join('\n') + '\n', { encoding: 'utf-8' });
    console.log(`✅ 清单文件: SHA256SUMS`);
  }
}

function main() {
  console.log('🚀 TurboTrans 预构建脚本启动...');

  const projectDir = resolve();
  console.log('项目目录:', projectDir);

  const hash = getConfigHash();
  if (checkLock(hash)) {
    return; // 跳过构建
  }

  const pluginDir = resolve(projectDir, 'TurboTransJSONPlugin');
  const outputDir = resolve('tpc', 'outputs', 'plugin');

  if (!existsSync(pluginDir)) {
    console.log(`⚠️ 插件目录不存在: ${pluginDir}`);
    return;
  }

  try {
    clearDir(outputDir);
    ensureDir(outputDir);

    buildPlugin(pluginDir);
    moveArtifact(pluginDir);
    signArtifacts();

    generateBuildLock(hash);
    console.log('🎉 构建完成！');

  } catch (error) {
    console.error('💥 构建失败:', error.message);
    // 清理锁文件，允许重试
    if (existsSync(resolve('.plugin-build.lock'))) {
      rmSync(resolve('.plugin-build.lock'), { force: true });
    }
    process.exit(1);
  }
}

main();